package sadi.server;

import sadi.util.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.net.MalformedURLException;

public class WikiServerImpl extends UnicastRemoteObject implements WikiServer
{
	//Instance Variables
	ServerGUI gui;
	DBHandler db;
	FileHandler fh;
	
	public WikiServerImpl(ServerGUI serverGUI) throws RemoteException
	{
		gui = serverGUI;
		db = new DBHandler();
		fh = new FileHandler("welcome.txt");
		
		//Check Database Connection
		if(!db.isConnected())
			gui.appendLog(true, "Database Error!\n");
	}
	
	
	
	/*************** USER HANDLING METHODS ***************/
	
	//Get Introduction Message
	public String getIntroduction() throws RemoteException
	{
		String response = fh.readFile();
		return (response != null)? response : "";
	}
	
	//Set Introduction Message
	public boolean setIntroduction(String message, int userID) throws RemoteException
	{
		//Check User's Administrative Rights
		if(db.isAdmin(userID))
		{
			fh.writeFile(message);
			return true;
		}
		else
			return false;
	}
	
	
	
	/*************** USER INTERFACE METHODS ***************/
	
	//Login A User
	//Success: Return UserID
	//Failure: Return -1
	public int loginUser(String username, String password) throws RemoteException
	{
		return db.loginUser(username, password);
	}
	
	//Register A User
	//Username Must Be Unique
	public boolean registerUser(String username, String password) throws RemoteException
	{
		if(db.registerUser(username, password))
		{
			gui.appendLog(true, username + " has registered.\n");
			return true;
		}
		else
			return false;
	}
	
	//Check User's Administrative Rights
	public boolean isAdmin(int userID) throws RemoteException
	{
		return db.isAdmin(userID);
	}
	
	
	
	/*************** WIKI LISTING HANDLING METHODS ***************/
	
	//Search Wiki Matches
	public ArrayList<ArrayList<String>> searchWiki(String title) throws RemoteException
	{
		return db.searchWiki(title);
	}
	
	//Get Latest Wiki Highlights
	public ArrayList<ArrayList<String>> getHighlightList() throws RemoteException
	{
		return db.getHighlightList();
	}
	
	//Get List of Wiki with the Specified Status
	public ArrayList<ArrayList<String>> getApprovalList(int userID) throws RemoteException
	{
		//Check User's Administrative Rights
		if(db.isAdmin(userID))
			return db.getStatusList("p");
		else
			return new ArrayList<ArrayList<String>>();
	}
	
	//Get List of Wiki with the Specified Status
	public ArrayList<ArrayList<String>> getReportedList( int userID) throws RemoteException
	{
		//Check User's Administrative Rights
		if(db.isAdmin(userID))
			return db.getStatusList("r");
		else
			return new ArrayList<ArrayList<String>>();
	}
	
	
	
	/*************** WIKI HANDLING METHODS ***************/
	
	//View Content of Wiki
	public ArrayList<String> viewWiki(int wikiID, int userID) throws RemoteException
	{
		//Check User's Administrative Rights
		if(db.isAdmin(userID))
			return db.viewAllWiki(wikiID);
		else
			return db.viewWiki(wikiID);
	}
	
	//Create a New Wiki With Content
	public boolean addWiki(String title, String description, String content, int userID) throws RemoteException
	{
		//Check Validity of UserID
		if(db.isValidUser(userID))
		{
			if(db.addWiki(title, description, content, userID))
			{
				gui.appendLog(true, "User " + userID + " added a new wiki! (Title: " + title + ")\n");
				return true;
			}
		}
		
		return false;
	}
	
	//Edit Wiki Contents
	public boolean editWiki(int wikiID, String title, String description, String content, int userID) throws RemoteException
	{
		//Check Validity of UserID
		if(db.isValidUser(userID))
		{
			if(db.editWiki(wikiID, title, description, content, userID))
			{
				gui.appendLog(true, "User " + userID + " edited \"" + title + "\".\n");
				return true;
			}
		}
		
		return false;
	}
	
	//Delete Wiki
	public boolean deleteWiki(int wikiID, int userID) throws RemoteException
	{
		boolean allow = false;
		
		//Admin User: Delete Any Wiki
		if(db.isAdmin(userID))
			allow = true;
		//Normal User: Delete Only His Own Wiki
		else if(db.isWikiOwner(wikiID, userID))
			allow = true;
		
		if(allow)
		{
			if(db.deleteWiki(wikiID))
			{
				gui.appendLog(true, "User " + userID + " deleted " + wikiID + ".\n");
				return true;
			}
		}
		
		return false;
	}
	
	//Report Wiki Contents
	public boolean addReport(int wikiID, int userID) throws RemoteException
	{
		//Check Validity of UserID
		if(db.isValidUser(userID))
		{
			if(db.addReport(wikiID, userID))
			{
				gui.appendLog(true, "User " + userID + " reported " + wikiID + " for abuse.\n");
				return true;
			}			
		}
		
		return false;
	}
	
	//Approve Wiki Contents
	public boolean approveWiki(int wikiID, int userID) throws RemoteException
	{
		//Check User's Administrative Rights
		if(db.isAdmin(userID))
		{
			if(db.approveWiki(wikiID))
			{
				gui.appendLog(true, "User " + userID + " approved changes to " + wikiID + ".\n");
				return true;
			}
		}
		
		return false;
	}
}
